package com.dy.yunying.biz.controller.datacenter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.dy.yunying.api.constant.Constant;
import com.dy.yunying.api.datacenter.dto.AdRecoveryDto;
import com.dy.yunying.api.datacenter.export.AdExportDataAnalysisVO;
import com.dy.yunying.api.datacenter.export.AdExportDataVo;
import com.dy.yunying.api.datacenter.export.AdExportRecoveryVo;
import com.dy.yunying.biz.service.datacenter.AdRecoveryService;
import com.dy.yunying.biz.utils.DateUtils;
import com.dy.yunying.biz.utils.ExportAlibabaUtils;
import com.dy.yunying.biz.utils.ExportUtils;
import com.dy.yunying.biz.utils.MapUtils;
import com.pig4cloud.pig.api.util.StringUtils;
import com.pig4cloud.pig.common.core.exception.BusinessException;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.plugin.excel.annotation.ResponseExcel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * 回收分析相关接口
 *
 * @author ：lile
 * @date ：2021/6/22 11:00
 * @description：
 * @modified By：
 */
@RestController("adRecovery")
@RequestMapping("/dataCenter/adRecovery")
@Slf4j
public class AdRecoveryController {

	private static final String[] LTV_KEYS = {"ltv1", "ltv2", "ltv3", "ltv4", "ltv5", "ltv6", "ltv7", "ltv8", "ltv9", "ltv10", "ltv11", "ltv12", "ltv13", "ltv14", "ltv15", "ltv16", "ltv17", "ltv18", "ltv19", "ltv20", "ltv21", "ltv22", "ltv23", "ltv24", "ltv25", "ltv26", "ltv27", "ltv28", "ltv29", "ltv30", "ltv45", "ltv60", "ltv75", "ltv90", "ltv120", "ltv150", "ltv180"};
	private static final String[] LTV_TIMES_KEYS = {"ltvtimes1", "ltvtimes2", "ltvtimes3", "ltvtimes4", "ltvtimes5", "ltvtimes6", "ltvtimes7", "ltvtimes8", "ltvtimes9", "ltvtimes10", "ltvtimes11", "ltvtimes12", "ltvtimes13", "ltvtimes14", "ltvtimes15", "ltvtimes16", "ltvtimes17", "ltvtimes18", "ltvtimes19", "ltvtimes20", "ltvtimes21", "ltvtimes22", "ltvtimes23", "ltvtimes24", "ltvtimes25", "ltvtimes26", "ltvtimes27", "ltvtimes28", "ltvtimes29", "ltvtimes30", "ltvtimes45", "ltvtimes60", "ltvtimes75", "ltvtimes90", "ltvtimes120", "ltvtimes150", "ltvtimes180"};
	private static final String[] ROI_KEYS = {"roi1", "roi2", "roi3", "roi4", "roi5", "roi6", "roi7", "roi8", "roi9", "roi10", "roi11", "roi12", "roi13", "roi14", "roi15", "roi16", "roi17", "roi18", "roi19", "roi20", "roi21", "roi22", "roi23", "roi24", "roi25", "roi26", "roi27", "roi28", "roi29", "roi30", "roi45", "roi60", "roi75", "roi90", "roi120", "roi150", "roi180"};

	private static final String[] ALL_KEYS;
	private static final String[] EXPORT_PERCENTAGE_KEYS;

	static {

		ALL_KEYS = new String[LTV_KEYS.length + LTV_TIMES_KEYS.length + ROI_KEYS.length];
		System.arraycopy(LTV_KEYS, NumberUtils.INTEGER_ZERO, ALL_KEYS, NumberUtils.INTEGER_ZERO, LTV_KEYS.length);
		System.arraycopy(LTV_TIMES_KEYS, NumberUtils.INTEGER_ZERO, ALL_KEYS, LTV_KEYS.length, LTV_TIMES_KEYS.length);
		System.arraycopy(ROI_KEYS, NumberUtils.INTEGER_ZERO, ALL_KEYS, LTV_KEYS.length + LTV_TIMES_KEYS.length, ROI_KEYS.length);

		EXPORT_PERCENTAGE_KEYS = new String[NumberUtils.INTEGER_ONE + LTV_TIMES_KEYS.length + ROI_KEYS.length];
		EXPORT_PERCENTAGE_KEYS[0] = "roiRatio";
		System.arraycopy(LTV_TIMES_KEYS, NumberUtils.INTEGER_ZERO, EXPORT_PERCENTAGE_KEYS, NumberUtils.INTEGER_ONE, LTV_TIMES_KEYS.length);
		System.arraycopy(ROI_KEYS, NumberUtils.INTEGER_ZERO, EXPORT_PERCENTAGE_KEYS, LTV_TIMES_KEYS.length + NumberUtils.INTEGER_ONE, ROI_KEYS.length);

	}

	@Autowired
	private AdRecoveryService adRecoveryService;

	/**
	 * 回收分析总数
	 *
	 * @param req
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/count")
	public R countDataTotal(@Valid @RequestBody AdRecoveryDto req) {
		return adRecoveryService.countDataTotal(req);
	}

	/**
	 * 回收分析分页列表
	 *
	 * @param req
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/list")
	public R selectAdRecoverySource(@Valid @RequestBody AdRecoveryDto req) {
		return adRecoveryService.selectAdRecoverySource(req);
	}

	/**
	 * 回收分析报表导出
	 *
	 * @param req
	 * @return
	 */
	@ResponseExcel(name = "回收分析报表导出", sheet = "回收分析报表导出")
	@RequestMapping("/export")
	public R export(@Valid @RequestBody AdRecoveryDto req, HttpServletResponse response, HttpServletRequest request) {
		try {
			List resultList = new ArrayList();
			String sheetName = "回收分析报表";
			// 临时采用循环查询解决数据过大的问题
			Long current = 1L;
			while (true) {
				req.setSize(1500L);
				req.setCurrent(current);
				List tmpList = (List) adRecoveryService.selectAdRecoverySource(req).getData();
				if (CollectionUtils.isEmpty(tmpList)) {
					break;
				}
				resultList.addAll(tmpList);
				current++;
			}
			// 查询汇总行-汇总只有一条
			if (StringUtils.isNotBlank(req.getQueryColumn()) || 4 != req.getCycleType()) {
				req.setSize(1L);
				req.setCurrent(1L);
				req.setCycleType(4);
				req.setQueryColumn(Constant.EMPTTYSTR);
				R collect = adRecoveryService.selectAdRecoverySource(req);
				resultList.addAll((List) collect.getData());
			}


			String fileName = URLEncoder.encode("回收分析报表-"+ DateUtils.getCurrentTimeNoUnderline(), "UTF-8").replaceAll("\\+", "%20");
			List<Map<String, Object>> resultListMap = MapUtils.objectsToMaps(resultList);
			List<AdExportRecoveryVo> list = this.convertListObject(resultListMap);

			ExportAlibabaUtils.exportExcelData(response,sheetName,fileName,req.getColumns(),list,AdExportRecoveryVo.class);

		} catch (BusinessException e) {
			log.error("export is error", e);
			throw e;
		} catch (Exception e) {
			log.error("export is error", e);
			throw new BusinessException("导出异常");
		}
		return null;
	}

	private List<AdExportRecoveryVo> convertListObject(List<Map<String, Object>> listMap) {
		for (Map<String, Object> map : listMap) {

			for (Map.Entry<String, Object> entry : map.entrySet()) {
				final String key = entry.getKey();

				if ("roiRatio".equals(key)) {
					final BigDecimal value = (BigDecimal) entry.getValue();
					final BigDecimal decimal = ObjectUtils.defaultIfNull((BigDecimal) map.get(key + "Num"), BigDecimal.ZERO);
					if (decimal.compareTo(BigDecimal.ZERO) > 0) {
						map.put(key, String.format("%s%%(%s)", BigDecimal.ZERO.equals(value) ? "0.00" : value, map.get("roiRatioNum")));
					} else {
						map.put(key, String.format("%s%%", BigDecimal.ZERO.equals(value) ? "0.00" : value));
					}
				} else if (ArrayUtils.contains(LTV_KEYS, key) || ArrayUtils.contains(LTV_TIMES_KEYS, key)) {
					final BigDecimal value = (BigDecimal) entry.getValue();
					final BigDecimal valueNum = (BigDecimal) map.get(key + "Num");
					map.put(key, String.format("%s(%s)", 0 == BigDecimal.ZERO.compareTo(value) ? "0" : value, 0 == BigDecimal.ZERO.compareTo(valueNum) ? "0" : valueNum));
				} else if (ArrayUtils.contains(ROI_KEYS, key)) {
					final BigDecimal value = (BigDecimal) entry.getValue();
					final BigDecimal valueNum = (BigDecimal) map.get(key + "Num");
					map.put(key, String.format("%s%%(%s)", BigDecimal.ZERO.equals(value) ? "0.00" : value, valueNum));
				}

			}

		}

			List<AdExportRecoveryVo> list= new ArrayList<>();

			JSONArray array = JSONArray.parseArray(JSON.toJSONString(listMap));

			for (int i = 0; i < array.size(); i++) {
				JSONObject jsonObject = array.getJSONObject(i);
				AdExportRecoveryVo detail = JSON.parseObject(String.valueOf(jsonObject), AdExportRecoveryVo.class);
				list.add(detail);
			}
			return list;
	}

}
